﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using Domain.Config;
using Microsoft.AspNetCore.Http.Extensions;
using Tlh.Common;
using Utility;
using Microsoft.AspNetCore.Mvc.Controllers;
using System.Reflection;

namespace FacadeApi.Extension
{
    public class SignFilter : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (filterContext.HttpContext.Request.Headers["Referer"].Equals("http://localhost:5000/swagger/index.html")) return;
            if (filterContext.HttpContext.Request.Headers["Referer"].Equals("http://api.jhgoulaifu.com:6001/swagger/index.html")) return;
            if (filterContext.HttpContext.Request.Headers["Referer"].Equals("http://81.68.83.153:6001/swagger/index.html")) return;
            ControllerActionDescriptor controllerActionDescriptor = filterContext.ActionDescriptor as ControllerActionDescriptor;

            if (controllerActionDescriptor.MethodInfo.GetCustomAttribute<NotHamcSignAttribute>() != null) return;

            var IsOpenHmac = SystemConfig.GetConfigByTime<Boolean>("系统配置", "Hmac开启", TimeSpan.FromDays(1));
            var hmacSecret = SystemConfig.GetConfigByTime<string>("系统配置", "HmacSecret", TimeSpan.FromDays(1));
            var userName = SystemConfig.GetConfigByTime<string>("系统配置", "HmacUserName", TimeSpan.FromDays(1));
            var clockSkew = SystemConfig.GetConfigByTime<int>("系统配置", "HmacClockSkew", TimeSpan.FromDays(1));

            if (!IsOpenHmac) return;

            var path = filterContext.HttpContext.Request.GetEncodedPathAndQuery();
            var x_date = filterContext.HttpContext.Request.Headers["X-Date"];
            var DeviceID = filterContext.HttpContext.Request.Headers["DeviceID"];
            var Content_md5 = filterContext.HttpContext.Request.Headers["Content-md5"];
            var proxy_authorization = filterContext.HttpContext.Request.Headers["proxy-authorization"];

            if (string.IsNullOrWhiteSpace(x_date)|| string.IsNullOrWhiteSpace(DeviceID) || string.IsNullOrWhiteSpace(Content_md5) || string.IsNullOrWhiteSpace(proxy_authorization) )
            {
                ContentResult contentResult = new ContentResult();
                contentResult.Content = "Hmac Verification failed None Params!";
                contentResult.StatusCode = 401;

                filterContext.Result = contentResult;
                return;
            }

            var src_date = DateTime.Parse(x_date);
            var f_date = DateTime.Now;

            var sub = (src_date - f_date).TotalSeconds;
            var s = sub < 0 ? -sub : sub;

            if (s > clockSkew)
            {
                ContentResult contentResult = new ContentResult();
                contentResult.Content = "Hmac Verification failed ByOutSkew!";
                contentResult.StatusCode = 401;

                filterContext.Result = contentResult;
                return;
            }

            var f_md5 = Md5Util.SiginMd5(path).ToLower();

            if (!f_md5.Equals(Content_md5))
            {
                ContentResult contentResult = new ContentResult();
                contentResult.Content = "Hmac Verification failed ByMd5!";
                contentResult.StatusCode = 401;

                filterContext.Result = contentResult;
                return;
            }

            var f_sign = MyHmacUtil.CreateToken($"x-date: {x_date}\ncontent-md5: {Content_md5}\ndeviceid: {DeviceID}", hmacSecret);
            var f_str = $"hmac username=\"{userName}\", algorithm=\"hmac-sha256\", headers=\"x-date content-md5 deviceid\", signature=\"{f_sign}\"";

           
            if (!f_str.Equals(proxy_authorization))
            {
                Console.WriteLine($"x-date: {x_date}\ncontent-md5: {Content_md5}\ndeviceid: {DeviceID}");
                Console.WriteLine($"Src Hamc: {proxy_authorization}");
                Console.WriteLine($"hmac username=\"{userName}\", algorithm=\"hmac-sha256\", headers=\"x-date content-md5 deviceid\", signature=\"{f_sign}\"");


                ContentResult contentResult = new ContentResult();
                contentResult.Content = "Hmac Verification failed!";
                contentResult.StatusCode = 401;

                filterContext.Result = contentResult;
            }
        }
    }
}
